import debounce from 'debounce';
const u = navigator.userAgent;
const isAndroid = u.includes('Android') || u.includes('Adr'); // android终端
const isWeixin = /miniProgram/i.test(u) && /micromessenger/i.test(u);
const isHarmony = u.indexOf('Harmony') > -1;
window.isWebviewInit = false;
function noop() {}

declare const window: any;

export function setup(callback: Function) {
  if (isWeixin) {
    return;
  }
  if (window.WebViewJavascriptBridge) {
    if (!window.isWebviewInit) {
      window.isWebviewInit = true;
      try {
        window.WebViewJavascriptBridge.init();
      } catch(e) {}
    }
    return callback(window.WebViewJavascriptBridge);
  } else if (isAndroid || isHarmony) {
    document.addEventListener('WebViewJavascriptBridgeReady', function() {
      if (!window.isWebviewInit) {
        window.isWebviewInit = true;
        try {
          window.WebViewJavascriptBridge.init();
        } catch(e) {}
      }
      callback(window.WebViewJavascriptBridge);
    });
  }
  if (window.WVJBCallbacks) {
    return window.WVJBCallbacks.push(callback);
  }
  window.WVJBCallbacks = [callback];
  const WVJBIframe = document.createElement('iframe');
  WVJBIframe.style.display = 'none';
  WVJBIframe.src = 'https://__bridge_loaded__';
  document.documentElement.appendChild(WVJBIframe);
  setTimeout(function () {
    document.documentElement.removeChild(WVJBIframe);
  }, 0);
}

const callbackObj: any = {
  navigationConfig: [],
  navigationBarHeight: [],
  popWebViewController: [],
  pushNativeViewController: [],
  shareDigitalKeyDetail: [],
  shareMessages: [],
  getToken: [],
  getCommunityDownloadToken: [],
  updateToken: [],
  getUserInfo: [],
  getCurrentPosition: [],
  getLocationAuthority: [],
  chooseMapNavigation: [],
  showDialog: [],
  showToast: [],
  hideToast: [],
  getPermissionAudio: [],
  getPermissionCamera: [],
  goPermissionSetting: [],
  logOut: [],
  clearCache: [],
  getCacheSize: [],
  getUserImage: [],
  getUserImageSize: [],
  getUserDefaultCarId: [],
  getImageSetting: [],
  getCameraSetting: [],
  getUserNotification: [],
  popCameraDialog: [],
  shareRecorder: [],
  startRecorder: [],
  stopRecorder: [],
  telPhone: [],
  bindWeChat: [],
  bindApple: [],
  jumpToStore: [],
  updateLocation: [],
  sharePosterImage: [],
  clearCookieCache: [],
  updateCapacity: []
};

setup(function (bridge: any) {
  for (const key in callbackObj) {
    // 鸿蒙回调
    window[`${key}CallBack`] = function(res: any) {
      const fn = callbackObj[key].shift();
      fn && fn(res);
    }
    // 安卓，ios回调
    bridge.registerHandler(`${key}CallBack`, function (res: any) {
      const fn = callbackObj[key].shift();
      let data = null;
      try {
        if (typeof JSON.parse(res) === 'object') {
          data = JSON.parse(res);
        } else {
          data = res;
        }
      } catch(e: any) {
        data = res;
      }
      fn && fn(data);
    });
  }
});

type navigationConfig = {
  showNavBar?: boolean;
  title: string;
  slideBack?: boolean;
  shareBtn?: boolean;
};
export function navigationConfig(params: navigationConfig, callback: Function = noop) {
  document.title = params.title;
  setup(function (bridge: any) {
    callbackObj.navigationConfig.push(callback);
    bridge.callHandler('navigationConfig', params);
  });
}

export function navigationBarHeight(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.navigationBarHeight.push(callback);
    bridge.callHandler('navigationBarHeight', '');
  });
}

export function popWebViewController(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.popWebViewController.push(callback);
    bridge.callHandler('popWebViewController', {});
    window.close();
  });
}

export const pushNativeViewController = debounce(function(params: any, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.pushNativeViewController.push(callback);
    bridge.callHandler('pushNativeViewController', params);
  });
}, 1000, {
  immediate: true
})

export function shareDigitalKeyDetail(params: any, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.shareDigitalKeyDetail.push(callback);
    bridge.callHandler('shareDigitalKeyDetail', params);
  });
}

type shareMessages = {
  isWeiBo: boolean;
  isWeChat: boolean;
  isWeChatFriend: boolean;
  isPoster: boolean;
  content: string;
  title: string;
  contentText: string;
  shareUrl: string;
  shareImageUrl: string;
  shareType: 1 | 2 | 3;
};
export function shareMessages(params: shareMessages, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.shareMessages.push(callback);
    bridge.callHandler('shareMessages', params);
  });
}

export function getToken(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getToken.push(callback);
    bridge.callHandler('getToken', '');
  });
}

export function updateToken(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.updateToken.push(callback);
    bridge.callHandler('updateToken', '');
  });
}

export function getUserInfo(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getUserInfo.push(callback);
    bridge.callHandler('getUserInfo', '');
  });
}

export function getCurrentPosition(callback: Function = noop) {
  setup(function (bridge: any) {
    console.log('getCurrentPosition', Date.now());
    callbackObj.getCurrentPosition.push(callback);
    bridge.callHandler('getCurrentPosition', '');
  });
}

export function getLocationAuthority(callback: Function = noop) {
  setup(function (bridge: any) {
    console.log('getLocationAuthority', Date.now())
    callbackObj.getLocationAuthority.push(callback);
    bridge.callHandler('getLocationAuthority', '');
  });
}

type chooseMapNavigation = {
  latitude: number;
  longitude: number;
  name: string;
};
export function chooseMapNavigation(params: chooseMapNavigation, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.chooseMapNavigation.push(callback);
    bridge.callHandler('chooseMapNavigation', params);
  });
}

type showDialogParams = {
  type?: string;
  title: string;
  content: string;
  left: string;
  right?: string;
  list?: any[];
  date?: Date;
  testObj?: Object;
};
export function showDialog(params: showDialogParams, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.showDialog.push(callback);
    bridge.callHandler('showDialog', params);
  });
}

type showToastParams = {
  type?: string;
  message: string;
  status?: 'success' | 'fail' | 'loading' | null | '';
};
export function showToast(params: showToastParams, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.showToast.push(callback);
    bridge.callHandler('showToast', params);
  });
}

export function hideToast(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.hideToast.push(callback);
    bridge.callHandler('hideToast', '');
  });
}

export function getPermissionAudio(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getPermissionAudio.push(callback);
    bridge.callHandler('getPermissionAudio', '');
  });
}

export function getPermissionCamera(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getPermissionCamera.push(callback);
    bridge.callHandler('getPermissionCamera', '');
  });
}

export function goPermissionSetting(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.goPermissionSetting.push(callback);
    bridge.callHandler('goPermissionSetting', '');
  });
}
export function logOut(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.logOut.push(callback);
    bridge.callHandler('logOut', '');
  });
}
export function clearCache(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.clearCache.push(callback);
    bridge.callHandler('clearCache', '');
  });
}
export function getCacheSize(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getCacheSize.push(callback);
    bridge.callHandler('getCacheSize', '');
  });
}
type imageParams = {
  maxImagesCount: number;
};
export function getUserImage(params: imageParams, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getUserImage.push(callback);
    bridge.callHandler('getUserImage', params);
  });
}

export function getUserImageSize(params: imageParams, callback: Function = noop) {
  if (isAndroid || isHarmony) {
    setup(function (bridge: any) {
      callbackObj.getUserImageSize.push(callback);
      bridge.callHandler('getUserImageSize', params);
    });
  }
}

export function getUserDefaultCarId( callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getUserDefaultCarId.push(callback);
    bridge.callHandler('getUserDefaultCarId', '');
  });
}

export function getCameraSetting( callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getCameraSetting.push(callback);
    bridge.callHandler('getCameraSetting', '');
  });
}

export function getImageSetting(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getImageSetting.push(callback);
    bridge.callHandler('getImageSetting', '');
  });
}

export function getUserNotification(params: { useLocation: 1 | 2 }, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getUserNotification.push(callback);
    bridge.callHandler('getUserNotification', params);
  });
}

export function popCameraDialog(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.popCameraDialog.push(callback);
    bridge.callHandler('popCameraDialog', '');
  });
}

export function shareRecorder(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.shareRecorder.push(callback);
    bridge.callHandler('shareRecorder', '');
  });
}

export function startRecorder(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.startRecorder.push(callback);
    bridge.callHandler('startRecorder');
  });
}

export function stopRecorder(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.stopRecorder.push(callback);
    bridge.callHandler('stopRecorder');
  });
}

export function telPhone(params: {phoneNum: string}, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.telPhone.push(callback);
    bridge.callHandler('telPhone', params);
  });
}

export function bindWeChat( callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.bindWeChat.push(callback);
    bridge.callHandler('bindWeChat');
  });
}

export function bindApple(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.bindApple.push(callback);
    bridge.callHandler('bindApple');
  });
}

export function jumpToStore(params: {downloadUrl: string}, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.jumpToStore.push(callback);
    bridge.callHandler('jumpToStore', params);
  });
}

export function updateLocation(params: { close: any, locateMode: number }, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.updateLocation.push(callback);
    console.log('updateLocationParams', params)
    bridge.callHandler('updateLocation', params);
  });
}

export function sharePosterImage(params: {imgUrl:string,title:string }, callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.sharePosterImage.push(callback);
    bridge.callHandler('sharePosterImage', params);
  });
}

export function clearCookieCache(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.clearCookieCache.push(callback);
    bridge.callHandler('clearCookieCache');
  });
}

export function updateCapacity(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.updateCapacity.push(callback);
    bridge.callHandler('updateCapacity');
  });
}

export function getCommunityDownloadToken(callback: Function = noop) {
  setup(function (bridge: any) {
    callbackObj.getCommunityDownloadToken.push(callback);
    bridge.callHandler('getCommunityDownloadToken', '');
  });
}
